import servers
import asyncio

#dict stores pointers to command objects
# keys are the names of the commands
commands = {}

#contains help about all commands
helpstring = "**Commands**: \n"

#gets initialized on ready, updates player counts
updater = None
async def init_updater():
	global updater
	updater = servers.Updater()
	loop = asyncio.get_event_loop()
	loop.create_task(updater.start())

class CommandNameError(Exception):
	def __init__(self, message):
		self.message = message

class Command:
	def __init__(self, names, help, fn):
		self.names = names #list of names the command responds to
		self.help = help #string added to help
		self.function = fn #args:(client, message), returns command response
		global helpstring
		for name in names:
			try:
				commands[name]
				raise CommandNameError("Duplicate: \'" + name + "\'")
			except KeyError:
				commands[name] = self
				helpstring = helpstring + "`" + name + "` "
		helpstring = helpstring + ": " + help + "\n"
		
	async def respond(self, client, message):
		msg = await self.function(client, message)
		await message.channel.send(msg)

#helper functions
def parse_arguments(msg):
	command_content = msg.content
	words = command_content.split()
	return words
def author_is_admin(message):
	isEran = message.author.id == 372460576485539840
	try:
		has_perms = message.author.permissions_in(message.channel).manage_channels
		return has_perms or isEran
	except AttributeError:
		return isEran
		

		
		
#Command definitions
#help
async def get_help(client, msg):
	args = parse_arguments(msg)
	try:
		return commands[args[1]].help
	except:
		return helpstring
Command(["help"], "Displays help about commands", get_help)
#source
async def show_source(client, msg):
	return "Can I see your guts too?\n" + \
		"https://notabug.org/NetherEran/Post_DvZ_Bot"
Command(["sauce", "source", "sourcecode", "code"],\
	"Shows a link to the source code", show_source)
#add mc server
async def addmc(client, msg):
	if author_is_admin(msg):
		return servers.add_mc_server(msg)
	else:
		return "You have insufficient permissions for this command."
Command(["addmcserver"],\
	"Admin only, adds player count updates to the channel it's used in. Arguments: ip, name, game threshold",\
	addmc)
async def force_count(client, msg):
	try:
		return await updater.force_update(msg.guild.id)
	except KeyError:
		return "This guild does not have a player counter"
Command(["count", "update"],\
	"Forces a player counter update and posts it in chat", \
	force_count)



#react to commands
async def handle_command(client, message):
	try:
		await commands[(message.content.split())[0][1:]].respond(client, message)
	except KeyError:
		await message.channel.send("Unknown Command")
		
